#ifndef __client_H__
#define __client_H__
#define BIGSIZE 102400
#define MAXSTR 1024
#define F_ret 0
#define S_ret 1
#include <func.h>
#include <curses.h>
#include <sys/io.h>
typedef struct train
{
    int len;
    char buf[MAXSTR];
} Train;
typedef struct
{
    unsigned int count[2];
    unsigned int state[4];
    unsigned char buffer[64];
} MD5_CTX;
int init_socket(char *, char *);
int send_cmd(int, char *str_stdin);
int sendn(int sfd, void *str, int len);
int recvn(int sfd, void *p, int len);
int deal_cmd(int sfd, char *str_stdin);
void send_file(int sfd, char *filename, off_t exist_size);
void recv_file(int sfd, char *filename);
int getpassword(char *passwd);
int login(int sfd);
int judge_file_exit(char *filename);
void send_big_file(int fd, int sfd, off_t file_size, off_t exist_size);
void send_reg_file(int fd, int sfd, off_t file_size);
void recv_big_file(int fd, int sfd, off_t filesize);
void recv_reg_file(int fd, int sfd, off_t filesize);
void send_user_mes(int sfd, int login_flag, char *username, char *passwd);
void do_puts(int sfd, char *filename);
int judge_md5_filesize(char *filename, char *md5_str, int cur_size);
int compute_file_md5(char *file_path, char *md5_str, int filesize);

#define MD5_SIZE 16
#define MD5_STR_LEN 32
#define READ_DATA_SIZE 1024
#define F(x, y, z) ((x & y) | (~x & z))
#define G(x, y, z) ((x & z) | (y & ~z))
#define H(x, y, z) (x ^ y ^ z)
#define I(x, y, z) (y ^ (x | ~z))
#define ROTATE_LEFT(x, n) ((x << n) | (x >> (32 - n)))

#define FF(a, b, c, d, x, s, ac)  \
    {                             \
        a += F(b, c, d) + x + ac; \
        a = ROTATE_LEFT(a, s);    \
        a += b;                   \
    }
#define GG(a, b, c, d, x, s, ac)  \
    {                             \
        a += G(b, c, d) + x + ac; \
        a = ROTATE_LEFT(a, s);    \
        a += b;                   \
    }
#define HH(a, b, c, d, x, s, ac)  \
    {                             \
        a += H(b, c, d) + x + ac; \
        a = ROTATE_LEFT(a, s);    \
        a += b;                   \
    }
#define II(a, b, c, d, x, s, ac)  \
    {                             \
        a += I(b, c, d) + x + ac; \
        a = ROTATE_LEFT(a, s);    \
        a += b;                   \
    }
void MD5Init(MD5_CTX *context);
void MD5Update(MD5_CTX *context, unsigned char *input, unsigned int inputlen);
void MD5Final(MD5_CTX *context, unsigned char digest[16]);
void MD5Transform(unsigned int state[4], unsigned char block[64]);
void MD5Encode(unsigned char *output, unsigned int *input, unsigned int len);
void MD5Decode(unsigned int *output, unsigned char *input, unsigned int len);
#endif
